#ifndef ENCODE_H264_AAC_H
#define ENCODE_H264_AAC_H
#include <queue>
#include <mutex>
#include <functional>
#include <condition_variable>
#include <vector>

extern "C" {
    #include <libavcodec/avcodec.h>
    #include <libavformat/avformat.h>
    #include <libavutil/imgutils.h>
    #include <libavutil/opt.h>
    #include <libswscale/swscale.h>
    #include <libavformat/avio.h>
    #include <libavutil/opt.h>
    #include <libavutil/samplefmt.h>
    #include <libavutil/channel_layout.h>
}

class ENCODE_H264_AAC {
public:
    ENCODE_H264_AAC();
    ~ENCODE_H264_AAC();

    //初始化h264编码器
    bool init_h264(int width, int height, int fps, int bitrate = 2000000);

    //初始化aac编码器
    bool init_aac(int sample_rate, int channels, int bitrate = 192000);

    //编码YUV420一帧
    bool encodeH264Frame(uint8_t * yuv420_data, std::function<void(AVPacket *)> packet_callback );

    //编码PCM一帧
    bool encodeAACFrame(uint16_t * pcm_data, int sampples ,std::function<void(AVPacket *)> packet_callback );

    void add_adts_header(uint8_t* buffer, int packet_size, int profile, int sample_rate, int channels);

    //获取编码后的包
    AVPacket* getH264Packet();

    AVPacket* getAACPacket();

    bool flushEncoder(std::function<void(AVPacket *)> packet_callback);

    AVRational get_time_base() const;

    //获取样本大小
    int getFrameSize();
    void cleanup();

private:
    /******************************video*************************/
    AVCodecContext* codec_ctx_;
    AVFrame* av_frame_;
    SwsContext* sws_ctx_;
    AVPacket* pkt_;
    int64_t pts_;
    int width_;
    int height_;
    int fps_;

    std::mutex queue_mutex_;
    std::queue<AVPacket*> packet_queue_;
    std::condition_variable queue_cv_;


    /******************************audio*************************/
    int sample_rate_;
    int channels_;
    int bit_rate_;
    int frame_size_;

    // PCM到浮点转换缓冲区
    std::vector<float> float_buffer_;
    // 累积 PCM 样本的缓冲区
    std::vector<uint16_t> pcm_buffer_;
    int pcm_buffer_samples_;

};

#endif